<template>
  <div id="detail">
    <detail-top-nav class="detailNav" @titleClick="titleClick" ref="topNav"/>
    <scroll class="detailScroll" ref="scroll" @scroll="topTitScroll" :probe-type="3">
      <DetailSwiper :top-images="topImages"/>
      <DetailBaseInfo :products="products"/>
      <DetailShopInfo :business="business"/>
      <DetailGoodsInfo :detail-info="detailInfo" @imageLoad="imageLoad"/>
      <DetailParamInfo ref="params" :param-info="paramsInfo"/>
      <DetailCommentInfo ref="comment" :comment-info="commentInfo"/>
      <ProductsList ref="recommend" :products="recommends"/>
    </scroll>
    <DetailBottomBar @addToCart="addToCart"/>
    <BackTop @click.native="BackTop" v-show="isShowBackTop"/>
  </div>
</template>

<script>
  import DetailTopNav from "./childComponents/DetailTopNav";
  import DetailSwiper from "./childComponents/DetailSwiper";
  import DetailBaseInfo from "./childComponents/DetailBaseInfo";
  import DetailShopInfo from "./childComponents/DetailShopInfo";
  import DetailGoodsInfo from "./childComponents/DetailGoodsInfo";
  import DetailParamInfo from "./childComponents/DetailParamInfo";
  import DetailCommentInfo from "./childComponents/DetailCommentInfo";
  import DetailBottomBar from "./childComponents/DetailBottomBar";

  import Scroll from "../../components/common/scroll/Scroll";
  import ProductsList from "../../components/content/product/ProductsList";

  import {getDetailData, Products, ProductsParam, getRecommends, Business} from "../../network/detail";
  import {itemImgListenerMixin, backTopMixin} from "../../common/mixin";
  import {debounce} from "../../common/utils";

  export default {
    name: "Detail",
    components: {
      DetailTopNav,
      DetailSwiper,
      DetailBaseInfo,
      DetailShopInfo,
      DetailGoodsInfo,
      DetailParamInfo,
      DetailCommentInfo,
      DetailBottomBar,
      Scroll,
      ProductsList
    },
    mixins: [itemImgListenerMixin, backTopMixin],
    data() {
      return {
        iid: null,
        topImages: [],
        products: {},
        business: {},
        detailInfo: {},
        paramsInfo: {},
        commentInfo: {},
        recommends: [],
        topTitleLocation: [],
        getTopTitleLocation: null,
        currentIndex: 0
      }
    },
    created() {
      //保存传入的iid
      this.iid = this.$route.params.iid

      //根据iid请求详情也中的相关数据
      getDetailData(this.iid).then(res => {
        // console.log(res);
        const detailData = res.result;
        //获取顶部的图片轮播数据
        this.topImages = detailData.itemInfo.topImages

        //获取商品的相关信息
        this.products = new Products(detailData.itemInfo, detailData.columns, detailData.shopInfo.services)

        //获取商家的相关信息
        this.business = new Business(detailData.shopInfo)

        //关于商品的详情数据
        this.detailInfo = detailData.detailInfo;

        //关于商品的参数相关信息
        this.paramsInfo = new ProductsParam(detailData.itemParams.info, detailData.itemParams.rule)

        //关于商品的评论相关信息
        if (detailData.rate.cRate !== 0) {
          this.commentInfo = detailData.rate.list[0]
        }

        //获取详情页中各个标题的offsetTop值
        //第一次获取：值不对，因为this.$refs.***.$el压根没有渲染
        /*this.topTitleLocation = []
        //商品的offsetTop
        this.topTitleLocation.push(0)
        //参数的offsetTop
        this.topTitleLocation.push(this.$refs.params.$el.offsetTop)
        //评论的offsetTop
        this.topTitleLocation.push(this.$refs.comment.$el.offsetTop)
        //推荐的offsetTop
        this.topTitleLocation.push(this.$refs.recommend.$el.offsetTop)
        console.log(this.topTitleLocation);*/

        //第二次获取：值不对，因为图片没有计算在内
        /*this.$nextTick(() => {
          //根据最新的数据，对应的Dom已经被渲染出来，但是图片并没有加载完成（获取到的offsetTop不包含其中的图片）
          //一般offsetTop值不对的时候，都是因为图片的问题
          this.topTitleLocation = []
          //商品的offsetTop
          this.topTitleLocation.push(0)
          //参数的offsetTop
          this.topTitleLocation.push(this.$refs.params.$el.offsetTop)
          //评论的offsetTop
          this.topTitleLocation.push(this.$refs.comment.$el.offsetTop)
          //推荐的offsetTop
          this.topTitleLocation.push(this.$refs.recommend.$el.offsetTop)
          console.log(this.topTitleLocation);
        })*/
      })

      //获取推荐数据
      getRecommends().then(res => {
        // console.log(res);
        this.recommends = res.data.list
      })

      //给getTopTitleLocation赋值
      this.getTopTitleLocation = debounce(() => {
        this.topTitleLocation = []
        //商品的offsetTop
        this.topTitleLocation.push(0)
        //参数的offsetTop
        this.topTitleLocation.push(this.$refs.params.$el.offsetTop)
        //评论的offsetTop
        this.topTitleLocation.push(this.$refs.comment.$el.offsetTop)
        //推荐的offsetTop
        this.topTitleLocation.push(this.$refs.recommend.$el.offsetTop)
        //填入一个js能获取的最大值
        this.topTitleLocation.push(Number.MAX_VALUE)
        // console.log(this.topTitleLocation);
      }, 200)
    },
    methods: {
      imageLoad() {
        this.$refs.scroll.refresh()

        this.getTopTitleLocation()
      },
      //点击标题滚动到对应的位置
      titleClick(index) {
        this.$refs.scroll.scrollTo(0, -this.topTitleLocation[index], 200)
      },
      //根据滚动的距离联动标题和显示回到顶部按钮
      topTitScroll(position) {
        //获取y值
        const positionY = -position.y
        //根据y值和标题中各个参数的y值比较（0, 13800, 15083, 15299,）
        //positionY在0~13800之间时，index=0
        //positionY在13800~15083之间时，index=1
        //positionY在15083~15299之间时，index=2
        //positionY大于15299时，index=3
        let length = this.topTitleLocation.length
        //最后一个值不需要遍历
        for (let i = 0; i < length - 1; i++) {
          //普通做法：this.currentIndex !== i && ((i < length - 1 && positionY >= this.topTitleLocation[i] && positionY < this.topTitleLocation[i + 1])|| (i === length - 1 && positionY >= this.topTitleLocation[i]))
          //(this.currentIndex !== i)条件1：防止赋值的过程过于频繁
          //(i < length - 1 && positionY >= this.topTitleLocation[i] && positionY < this.topTitleLocation[i + 1])条件2.1：判断区间
          //(i === length - 1 && positionY >= this.topTitleLocation[i])条件2.2：判断大于等于
          /*if (this.currentIndex !== i && ((i < length - 1 && positionY >= this.topTitleLocation[i] && positionY < this.topTitleLocation[i + 1])
            || (i === length - 1 && positionY >= this.topTitleLocation[i]))) {
            this.currentIndex = i;
            this.$refs.topNav.currentIndex = this.currentIndex
          }*/
          //hack做法：将条件2.2与条件2.1合并成一个条件，即给条件2.2也设置一个区间，给一个很大的值（Number.MAX_VALUE）
          //这个很大的值没必要遍历
          if (this.currentIndex !== i && (positionY >= this.topTitleLocation[i] && positionY < this.topTitleLocation[i + 1])) {
            this.currentIndex = i;
            this.$refs.topNav.currentIndex = this.currentIndex
          }
        }

        //根据滚动距离显示回到顶部按钮
        this.isShowBackTop=(-position.y) >= 1200
      },
      //将商品添加到购物车
      addToCart() {
        //获取购物车要展示的信息（图片、标题、描述、价格）
        const product = {}
        product.image = this.topImages[0];
        product.title = this.products.title;
        product.desc = this.products.desc;
        product.price = this.products.realPrice;
        product.iid = this.iid;

        //将商品添加到购物车中
        //针对mutations中方法的调用
        // this.$store.commit('addCart', product)
        //针对actions中方法的调用
        this.$store.dispatch('addCart', product)
          //当商品成功加入购物车时弹出一条提示信息(Toast)
          .then(resolve => {
            //普通方式封装的Toast
            /*this.isShow=true;
            this.message=resolve;
            setTimeout(() => {
              this.isShow=false;
              this.message=''
            },2000)*/
            //精简方式封装
            this.$toast.toastShow(resolve)
        })
      }
    },
    destroyed() {
      //取消全局事件的监听
      this.$bus.$off('itemImgLoad', this.itemImageListener)
    }
  }
</script>

<style scoped>
  #detail {
    position: relative;
    z-index: 12;
    background-color: #fff;
    height: 100vh;
  }

  .detailNav {
    position: relative;
    z-index: 10;
    background-color: #fff;
  }

  .detailScroll {
    height: calc(100% - 44px - 58px);
  }
</style>
